import logging
import os
import time

from django.contrib.auth.hashers import make_password, check_password
from django.db.models import Q
from django.http import JsonResponse
from django.views.decorators.http import require_POST

from business import helper
from users.models import Users, Token
from users.tools import utils, auth
from users.tools.auth import generate_token, decode_token, get_account
from users.tools.response import RspMsg

# 指定所用的logger
logger = logging.getLogger('stu')


# Create your views here.
def token_expired(request):
    msg = RspMsg()
    msg.error(666, "登录已过期，请重新登录")
    return JsonResponse(msg.get_result())


# 登录
@require_POST
def login(request):
    account = request.ask['account']
    password = request.ask['password']

    rst = RspMsg()
    try:
        query = Users.objects.get(account=account, status=0)
        if not check_password(password, query.password):
            raise PermissionError('error password exception')
        ip = utils.get_ip(request)
        token = generate_token(account, ip)
        token_model = Token.objects.filter(account=account)
        if token_model.exists():
            token_model.token = token
            token_model.update()
        else:
            token_model = Token()
            token_model.account = account
            token_model.token = token
            token_model.save()
        rst.data = {"token": token, 'who': account}
        rst.ok()
    except Exception as e:
        if type(e) is PermissionError:
            logger.exception(msg="密码错误")
            rst.error('500', '密码错误')
        else:
            logger.exception("登录异常")
            rst.error('501', '登录异常，请联系管理员')
    finally:
        return JsonResponse(rst.get_result())


@require_POST
def get_menu(request):
    rsp = RspMsg()
    token = request.ask['token']
    status, payload = auth.decode_token(token)
    who = auth.get_account(payload)
    is_admin = Users.objects.get(account=who).auth == 1
    rsp.data['menu'] = helper.make_menu(is_admin)
    return JsonResponse(rsp.get_result())


# 登出
@require_POST
def logout(request):
    status, payload = decode_token(request.ask['token'])
    account = get_account(payload)
    target = Token.objects.filter(account=account)
    if target.exists():
        target.delete()
    rsp = RspMsg()
    return JsonResponse(rsp.get_result())


# 展示用户列表
@require_POST
def show_users(request):
    current_page = request.ask['currentPage']  # 当前页数
    current_size = request.ask['currentSize']  # 当前每页个数
    from business.helper import page_n
    users = Users.objects.all().values('id', 'account', 'belongs', 'add_date', 'status', 'auth').order_by('-auth',
                                                                                                          'status')
    rsp = RspMsg()
    data = page_n(users, current_page, current_size)

    req_users = list(data.object_list)
    rsp.data = {
        'users': req_users,
        'currentPage': current_page,
        'currentSize': current_size,
        'totalCount': users.count()
    }
    return JsonResponse(rsp.get_result())


# 注册
@require_POST
def sign_up(request):
    rsp = RspMsg()
    query = Users.objects.filter(Q(account=request.ask['account']) | Q(belongs=request.ask['belongs']))
    if query.exists():
        rsp.error(500, '账号或归属人已存在')
    else:
        try:
            target = Users()
            target.account = request.ask['account']
            target.belongs = request.ask['belongs']
            target.password = make_password(request.ask['password'])
            target.add_date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            target.save()
        except Exception as e:
            logger.exception("注册时异常，请联系管理员")
            rsp.error(501, '注册时异常，请联系管理员')
    return JsonResponse(rsp.get_result())


# 更改用户状态
@require_POST
def change_status(request):
    target_id = request.ask['id']
    target_user = Users.objects.get(id=target_id)
    rsp = RspMsg()
    if target_user:
        target_user.status = request.ask['status']
        target_user.save()
        rsp.ok()
    else:
        rsp.error(500, "没有找到用户")
    return JsonResponse(rsp.get_result())


# 更新用户数据
@require_POST
def update_user(request):
    rst = RspMsg()
    try:
        target = Users.objects.get(account=request.ask['account'])
        target.belongs = request.ask['belongs']
        target.password = make_password(request.ask['password'])
        target.save()
    except Exception as e:
        logger.exception("用户数据更新失败")
        rst.error(500, '存储错误，请检查')
    else:
        rst.ok()
    return JsonResponse(rst.get_result())


# 查询用户
@require_POST
def query_user(request):
    current_page = request.ask['currentPage']  # 当前页数
    current_size = request.ask['currentSize']  # 当前每页个数
    users = Users.objects.filter(
        Q(account__contains=request.ask['searchInfo']) | Q(belongs__contains=request.ask['searchInfo'])) \
        .values('id', 'account', 'belongs', 'add_date', 'status', 'auth').order_by('-auth', 'status')

    from business.helper import page_n
    data = page_n(users, current_page, current_size)
    req_users = list(data.object_list)
    rsp = RspMsg()
    rsp.data = {
        'users': req_users,
        'currentPage': current_page,
        'currentSize': current_size,
        'totalCount': users.count()
    }
    return JsonResponse(rsp.get_result())


# 删除用户
@require_POST
def delete_user(request):
    from DataPlatform.settings import STATIC_ROOT
    from business.models import DesignPlan, OptConfig, OptResult, CalResult
    rsp = RspMsg()
    user_id = request.ask['id']
    file_root = STATIC_ROOT + '/business/user_params_file/'
    design_plans = DesignPlan.objects.filter(belongs=user_id).values('design_id')
    for i in design_plans:
        CalResult.objects.filter(design_id=i['design_id']).delete()
        if not os.path.exists(file_root):
            pass
        else:
            for filename in os.listdir(file_root):
                if filename.endswith(i['design_id']):
                    os.remove(file_root + filename)
    DesignPlan.objects.filter(belongs=user_id).delete()

    opt_configs = OptConfig.objects.filter(belongs=user_id).values('opt_id')
    for i in opt_configs:
        OptResult.objects.filter(opt_id=i['opt_id']).delete()
        if not os.path.exists(file_root):
            pass
        else:
            for filename in os.listdir(file_root):
                if filename.endswith(i['opt_id']):
                    os.remove(file_root + filename)
    OptConfig.objects.filter(belongs=user_id).delete()
    Users.objects.filter(id=user_id).delete()
    return JsonResponse(rsp.get_result())
